#include "General/General.h"

enum DetectorState
{
    LIGHTS_NOT_FOUND = 0,
    LIGHTS_FOUND = 1,
    ARMOR_NOT_FOUND = 2,
    ARMOR_FOUND = 3
};

struct ArmorParam{
    int color_threshold;
    int bright_threshold;

    float min_area;
    float max_angle;

    float max_angle_diff;
    float max_lengthDiff_ratio;
    float max_deviation_angle;

    float max_y_diff_ratio;
    float max_x_diff_ratio;

    ArmorParam()
    {
        color_threshold = 100-20;
        bright_threshold = 60;

        min_area = 50;
        max_angle = 45;

        max_angle_diff = 6;
        max_lengthDiff_ratio = 0.5;
        max_deviation_angle = 50;

        max_y_diff_ratio = 0.5;
        max_x_diff_ratio = 4.5;
    }
};
extern ArmorParam armorParam;

class LightBar
{
public:
    LightBar();
    LightBar(const RotatedRect& light);
    ~LightBar();

public:
    RotatedRect lightRect;
    float length;
    Point2f center;
    float angle;

};

class ArmorBox
{
public:
    ArmorBox();

    ArmorBox(const LightBar& l_light, const LightBar& r_light);

    ~ArmorBox();

    float getAngleDiff() const;

    float getDeviationAngle() const;

    float getDislocationX() const;

    float getDislocationY() const;

    float getLengthRation() const;

    bool isSuitableArmor() const;

public:
    LightBar l_light, r_light;
    int l_index, r_index;
    //int armorNum;
    vector<Point2f> armorVertices;
    ArmorType type;
    Point2f center;
    Rect armorRect;
    float armorAngle;
    Mat armorImg;

};

class ArmorDetector
{
public:
    ArmorDetector();
    ~ArmorDetector();

    void resetDetector();

    void setEnemyColor(Color enemyColor);

    void PreprocessImg(Mat& src);

    void findLights();

    void matchArmors();

    void setTargetArmor();

    void run(Mat& src);

    void showDebugInfo(bool showSrcImg_ON, bool showSrcBinary_ON, bool showLights_ON, bool showArmors_ON, bool textLights_ON, bool textArmors_ON, bool textScores_ON);

private:
    Mat srcImg;
    Mat srcImg_binary;
    vector<LightBar> lights;
    vector<ArmorBox> armors;
    ArmorBox targetArmor;
    ArmorBox lastArmor;
    DetectorState states;
    Color enemyColor;
};
